using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._AnalysisTools._Proximity
{
    /// <summary>
    /// <para>Generate Near Table</para>
    /// <para>Calculates distances and other proximity information between features in one or more feature class or layer. Unlike the Near tool, which modifies the input, Generate Near Table writes results to a new stand-alone table and supports finding more than one near feature.</para>
    /// <para>计算一个或多个要素类或图层中要素之间的距离和其他邻近信息。与修改输入的“邻近”工具不同，“生成邻近表”将结果写入新的独立表，并支持查找多个邻近要素。</para>
    /// </summary>    
    [DisplayName("Generate Near Table")]
    public class GenerateNearTable : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public GenerateNearTable()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_in_features">
        /// <para>Input Features</para>
        /// <para>The input features that can be point, polyline, polygon, or multipoint type.</para>
        /// <para>输入要素可以是点、折线、面或多点类型。</para>
        /// </param>
        /// <param name="_near_features">
        /// <para>Near Features</para>
        /// <para>One or more layer of feature class containing near feature candidates. The near features can be of point, polyline, polygon, or multipoint. If multiple layers or feature classes is specified, a field named NEAR_FC is added to the input table and will store the paths of the source feature class containing the nearest feature found. The same feature class or layer may be used as both input and near features.</para>
        /// <para>包含邻近候选要素的一个或多个要素类图层。近似要素可以是点、折线、面或多点。如果指定了多个图层或要素类，则会将一个名为 NEAR_FC 的字段添加到输入表中，并将存储包含找到的最近要素的源要素类的路径。同一要素类或图层可同时用作输入要素和近要素。</para>
        /// </param>
        /// <param name="_out_table">
        /// <para>Output Table</para>
        /// <para>The output table containing the result of the analysis.</para>
        /// <para>包含分析结果的输出表。</para>
        /// </param>
        public GenerateNearTable(object _in_features, List<object> _near_features, object _out_table)
        {
            this._in_features = _in_features;
            this._near_features = _near_features;
            this._out_table = _out_table;
        }
        public override string ToolboxName => "Analysis Tools";

        public override string ToolName => "Generate Near Table";

        public override string CallName => "analysis.GenerateNearTable";

        public override List<string> AcceptEnvironments => ["extent", "scratchWorkspace", "workspace"];

        public override object[] ParameterInfo => [_in_features, _near_features, _out_table, _search_radius, _location.GetGPValue(), _angle.GetGPValue(), _closest.GetGPValue(), _closest_count, _method.GetGPValue()];

        /// <summary>
        /// <para>Input Features</para>
        /// <para>The input features that can be point, polyline, polygon, or multipoint type.</para>
        /// <para>输入要素可以是点、折线、面或多点类型。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Features")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _in_features { get; set; }


        /// <summary>
        /// <para>Near Features</para>
        /// <para>One or more layer of feature class containing near feature candidates. The near features can be of point, polyline, polygon, or multipoint. If multiple layers or feature classes is specified, a field named NEAR_FC is added to the input table and will store the paths of the source feature class containing the nearest feature found. The same feature class or layer may be used as both input and near features.</para>
        /// <para>包含邻近候选要素的一个或多个要素类图层。近似要素可以是点、折线、面或多点。如果指定了多个图层或要素类，则会将一个名为 NEAR_FC 的字段添加到输入表中，并将存储包含找到的最近要素的源要素类的路径。同一要素类或图层可同时用作输入要素和近要素。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Near Features")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public List<object> _near_features { get; set; }


        /// <summary>
        /// <para>Output Table</para>
        /// <para>The output table containing the result of the analysis.</para>
        /// <para>包含分析结果的输出表。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Table")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _out_table { get; set; }


        /// <summary>
        /// <para>Search Radius</para>
        /// <para>The radius used to search for near features. If no value is specified, all near features will be candidates. If a distance is entered, but the unit is left blank or set to Unknown, the units of the coordinate system of the input features are used. If the Geodesic option is used in the Method parameter, a linear unit such as Kilometers or Miles should be used.</para>
        /// <para>用于搜索邻近要素的半径。如果未指定值，则所有邻近要素均为候选要素。如果输入距离，但单位留空或设置为未知，则使用输入要素坐标系的单位。如果在方法参数中使用了测地线选项，则应使用线性单位，例如“公里”或“英里”。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Search Radius")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _search_radius { get; set; } = null;


        /// <summary>
        /// <para>Location</para>
        /// <para><xdoc>
        ///   <para>Specifies whether x- and y-coordinates of the input feature's location and nearest location of the near feature will be written to FROM_X, FROM_Y, NEAR_X, and NEAR_Y fields.</para>
        ///   <bulletList>
        ///     <bullet_item>Unchecked—Locations will not be written to the output table. This is the default.</bullet_item><para/>
        ///     <bullet_item>Checked—Locations will be written to the output table.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定是否将输入要素的位置和邻近要素的最近位置的 x 和 y 坐标写入 FROM_X、FROM_Y、NEAR_X 和 NEAR_Y 字段。</para>
        ///   <bulletList>
        ///     <bullet_item>未选中 - 不会将位置写入输出表。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>选中 - 位置将写入输出表。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Location")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _location_value _location { get; set; } = _location_value._false;

        public enum _location_value
        {
            /// <summary>
            /// <para>LOCATION</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("LOCATION")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_LOCATION</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_LOCATION")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Angle</para>
        /// <para><xdoc>
        ///   <para>Specifies whether the near angle will be calculated and written to a NEAR_ANGLE field in the output table. A near angle measures direction of the line connecting an input feature to its nearest feature at their closest locations. When the Planar method is used in the Method parameter, the angle is within the range of -180° to 180°, with 0° to the east, 90° to the north, 180° (or -180°) to the west, and -90° to the south. When the Geodesic method is used, the angle is within the range of -180° to 180°, with 0° to the north, 90° to the east, 180° (or -180°) to the south, and -90° to the west.</para>
        ///   <bulletList>
        ///     <bullet_item>Unchecked—NEAR_ANGLE will not be added to the output table. This is the default.</bullet_item><para/>
        ///     <bullet_item>Checked—NEAR_ANGLE will be added to the output table.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定是否计算近角并将其写入输出表中的NEAR_ANGLE字段。近角测量将输入要素连接到其最近位置的最近要素的线的方向。在方法参数中使用平面方法时，角度在 -180° 到 180° 的范围内，东 0°，北 90°，西 180°（或 -180°），南 -90°。使用测地线方法时，角度在 -180° 到 180° 的范围内，北为 0°，东为 90°，南为 180°（或 -180°），西为 -90°。</para>
        ///   <bulletList>
        ///     <bullet_item>未选中 - 不会将NEAR_ANGLE添加到输出表中。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>选中 - NEAR_ANGLE将添加到输出表中。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Angle")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _angle_value _angle { get; set; } = _angle_value._false;

        public enum _angle_value
        {
            /// <summary>
            /// <para>ANGLE</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("ANGLE")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_ANGLE</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_ANGLE")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Find only closest feature</para>
        /// <para><xdoc>
        ///   <para>Specifies whether to return only the closest features or multiple features.</para>
        ///   <bulletList>
        ///     <bullet_item>Checked—Only the closest near feature will be written to the output table. This is the default.</bullet_item><para/>
        ///     <bullet_item>Unchecked—Multiple near features will be written to the output table (a limit can be specified in the Maximum number of closest matches parameter).</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定是仅返回最接近的要素还是多个要素。</para>
        ///   <bulletList>
        ///     <bullet_item>选中 - 仅将最近的邻近要素写入输出表。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>未选中 - 多个邻近要素将写入输出表（可在最大最近匹配项数参数中指定限制）。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Find only closest feature")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _closest_value _closest { get; set; } = _closest_value._true;

        public enum _closest_value
        {
            /// <summary>
            /// <para>CLOSEST</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("CLOSEST")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>ALL</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("ALL")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Maximum number of closest matches</para>
        /// <para>Limit the number of near features reported for each input feature. This parameter is disabled if Find only closest feature is checked.</para>
        /// <para>限制为每个输入要素报告的近似要素数。如果选中仅查找最近要素，则禁用此参数。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Maximum number of closest matches")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public long _closest_count { get; set; } = 0;


        /// <summary>
        /// <para>Method</para>
        /// <para><xdoc>
        ///   <para>Specifies whether to use a shortest path on a spheroid (geodesic) or a flat earth (planar). It is strongly suggested to use Geodesic method with data stored in a coordinate system which is not appropriate for distance measurements (for example, Web Mercator and any geographic coordinate system), or any dataset which spans a large geographic area.</para>
        ///   <bulletList>
        ///     <bullet_item>Planar—Uses planar distances between the features. This is the default.</bullet_item><para/>
        ///     <bullet_item>Geodesic—Uses geodesic distances between features. This method takes into account the curvature of the spheroid and correctly deals with data near the dateline and poles.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定是在椭球体（测地线）还是平坦地球（平面）上使用最短路径。强烈建议将测地线方法用于存储在不适合距离测量的坐标系（例如，Web 墨卡托和任何地理坐标系）或任何跨越较大地理区域的数据集中的数据。</para>
        ///   <bulletList>
        ///     <bullet_item>平面 （Planar） - 使用要素之间的平面距离。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>测地线 - 使用要素之间的测地线距离。该方法考虑了椭球体的曲率，并正确处理了日期变更线和极点附近的数据。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Method")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _method_value _method { get; set; } = _method_value._PLANAR;

        public enum _method_value
        {
            /// <summary>
            /// <para>Planar</para>
            /// <para>Planar—Uses planar distances between the features. This is the default.</para>
            /// <para>平面 （Planar） - 使用要素之间的平面距离。这是默认设置。</para>
            /// </summary>
            [Description("Planar")]
            [GPEnumValue("PLANAR")]
            _PLANAR,

            /// <summary>
            /// <para>Geodesic</para>
            /// <para>Geodesic—Uses geodesic distances between features. This method takes into account the curvature of the spheroid and correctly deals with data near the dateline and poles.</para>
            /// <para>测地线 - 使用要素之间的测地线距离。该方法考虑了椭球体的曲率，并正确处理了日期变更线和极点附近的数据。</para>
            /// </summary>
            [Description("Geodesic")]
            [GPEnumValue("GEODESIC")]
            _GEODESIC,

        }

        public GenerateNearTable SetEnv(object extent = null, object scratchWorkspace = null, object workspace = null)
        {
            base.SetEnv(extent: extent, scratchWorkspace: scratchWorkspace, workspace: workspace);
            return this;
        }

    }

}